/**
 * 
 */
package nlp.textToNumber;

import java.util.Map;

/**
 * @author pratibind
 * limitation: ONE MILLION SEVEN HUNDRED TWENTY ONE THOUSAND FOUR HUNDRED TWENTY FOUR
 *
 */
public class TextMappingTONumber {
	
	
	public static String[] tokenizInput(String input) {
		
		if(input.isEmpty())
			return null;
		
		String[] token = new String[50];
		
		token = input.split(" ");
		return token;
	}
	
	/*
	 * @parse the input value from table
	 * if it could not parse than return -1.
	 */
	public int parse(String data) {
		MappingTable tableObj = new MappingTable();
		Map<String, Integer> mapTable = tableObj.getDatatable();
		
		int val;
		
		try {
			val = Integer.parseInt(data);
			
		}catch(NumberFormatException num_e) {
			if(mapTable.containsKey(data)) {
				val = mapTable.get(data);
			}
			else{
				System.out.println("word "+data + " is unknown");
				return -1;
			}
		}
		
		return val;
	}
	
	//evaluate the text input to integer.
	public int eval(String[] input, int low , int high) {
		
		if(high < low ) {
			//System.out.println("Empty String");
			return -1;
		}
		
		if(low == high)
			return parse(input[low].toLowerCase());
		String data[] = input; 
		
		
		int expr=1;
		
		if(data != null) {
			
			for (int i = low; i <= high; i++) {
				//if text itself is number like "5"
				int value = parse(data[i].toLowerCase());
				//System.out.println(value);
				if(value == 0)
						return 0;
				//if number is not parse properly than
				if(value == -1)
						return value;
				
				//expr is less than value e.g "one thousand" so expr = 1 
				// values = 1000 so it should evaluated as 1 * 1000
				if(expr <= value)
					expr = expr*value;
				else if(expr > value) {
					//pointing to next number
					int j = i+1;
					//to handle condition like "1 thousand two hundred forty five"
					
					if(data.length > i+1){
						int nextval = parse(data[i+1].toLowerCase());
						if((nextval > value) && (nextval < expr)) {
							expr = expr + (value*nextval);
							++i;
						}else{
							expr = expr + value;
						}
					}	
					else{
						expr = expr + value;
					}
				}
			}
		}else{
			return -1;
		}
		return expr;
	}
	
	/*
	 * return maximum values  index
	 */
	public int getMaxInfo(String[] array, int low, int high) {
		
		if(low > high)
			return -1;
		
		if(low == high)
			return low;
		
		
		int max = parse(array[low].toLowerCase());
		
		if(max == -1)
			return -1;
		int max_index= low;
		for (int i = low+1; i < high; i++) {
			int temVal = parse(array[i].toLowerCase());
			
			//there is problem in parsing 
			if(temVal == -1)
				return -1;
			
			if(temVal >= max) {
				max = temVal;
				max_index = i;
			}
		}
		
		
		return max_index;
		
		
	}
	 
	//function which will give you final solutions
	//it will internally call eval function.
	public int solutions(String input) {
		
		if(input.isEmpty())
			return -1;
		
		String values[] = tokenizInput(input);
		
		/*
		 * logic is find maximum values and send this number from low to index 
		 * of max for evaluation and add the result to final expression.
		 */
		int solutions = 0;
		int index = 0;
		int high;
		while(index < values.length) {
			high = getMaxInfo(values, index,values.length);
			//System.out.println(high);
			if(high == -1 )
				return -1;
			
			solutions += eval(values, index, high);
			index = high+1;
		}
		//dummy return
		return solutions;
	}

}
